/*  BlogBotSimulator.java Version 102 - 18th June 2008
 *  BlogBotSimulator.java simulates serial input for the Blog Bot
 *  See Versions for program version number
 *  Copyright (C) 2008  Andy Broomfield andy@newmediathinking.com
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/

package net.blogbotplatform.blogbot;

public class BlogBotSimulator {

		static int simVal;   						//simulated sensor value;
		static int simStep;  						//steps to target sensor value
		static int SIM_CHANGE_BIAS = 50;			//chance out of 100 that the value will change
		static int SIM_STEP_MAX = 3;				//range for the simStep
		static int simNoise;						//random noise to be added to simulated sensor value
		static int SIM_NOISE_RANGE = 5;				//range for added noise
		static int simTarget;						//target value for simulation to reach
		static int NEW_SIM_TARGET_RANGE = 80;		//range for new target values
		static long changeTimer;					//timer to determine when to change target value
		static long nextChange;						//value of next change
		static int CHANGE_MAX = 1200000;				//fixed interval for changing timer
		static int CHANGE_MIN = 300000;				//fixed interval (min) changing timer
		static int SHORT_CHANGE_MAX = 2000;		//fixed interval for changing timer (short)
		
		static int protocolPos;
		static int NUM_OF_SIM_SENSORS = 1;
		
		static int DO_SHORT_CHANGE_BIAS = 90;
	
	public BlogBotSimulator() {
		simVal = (int)Math.floor(Math.random() * 240);
		simTarget = simVal;
		simNoise = 0;
		changeTimer = System.currentTimeMillis();
		nextChange = changeTimer + (int)Math.floor(Math.random() * SHORT_CHANGE_MAX);
		resetSimRandomness();
	}
	
	void runSimulator() {
		simulateSensorValue();			//simulate sensor
		BlogBotShop.serialValue(255);	//send end protocol message
		//at each change interval, reset the randomness settings
		if (System.currentTimeMillis() > nextChange) {
			changeTimer();
			resetSimRandomness();
		}
	}
	
	void changeTimer() {
		int randomNumber = (int)Math.floor(Math.random() * 99); 
		if (randomNumber < DO_SHORT_CHANGE_BIAS) {
			changeTimer = System.currentTimeMillis();
			nextChange = changeTimer + (int)Math.floor(Math.random() * SHORT_CHANGE_MAX);
		} else {
			int differnce = CHANGE_MAX - CHANGE_MIN;
			changeTimer = System.currentTimeMillis();
			nextChange = changeTimer + (int)Math.floor(Math.random() * differnce) + CHANGE_MIN;
		}
	}
	
	//simulates the sensor value, the idea is to have randomness stepping, but does not have to be too accurate
	void simulateSensorValue() {
		// only alter the simulated sensor value SIM_CHANGE_BIAS / 100
		int randomNumber = (int)Math.floor(Math.random() * 99); 
		if (randomNumber < SIM_CHANGE_BIAS) {
			if (simVal < simTarget) simVal = simVal + simStep;
			if (simVal > simTarget) simVal = simVal - simStep;
			simNoise = (int)Math.floor(Math.random() * SIM_NOISE_RANGE) - (int)(SIM_NOISE_RANGE / 2);
			simVal = simVal + simNoise;
			if (simVal > 240) simVal = 240;
			if (simVal < 0) simVal = 0;
		}
		//System.out.println("Simulated Value : " + simVal);
		BlogBotShop.serialValue(simVal);
	}
	
	void resetSimRandomness() {
		simStep = (int)Math.floor(Math.random() * SIM_STEP_MAX) + 1;
		simTarget = simTarget + (int)Math.floor(Math.random() * NEW_SIM_TARGET_RANGE) - (int)(NEW_SIM_TARGET_RANGE / 2);
		System.out.println(simTarget);
		if (simTarget > 240) simTarget = 240 - (int)Math.floor(Math.random() * (NEW_SIM_TARGET_RANGE / 2));
		if (simTarget < 0) simTarget = (int)Math.floor(Math.random() * (NEW_SIM_TARGET_RANGE / 2));
		System.out.println("new target : " + simTarget);
	}
}
